In the era of distributed development, it is common for large applications to be assembled from multiple components that are developed by different development teams. As an example, an application such as ECLIPSE™ software has sixty different components (or “plug-ins”) which are combined into a single large application. Some of these components are open-source third-party components such as ant; other components constitute the core application, but are built by separate teams. Similarly, for e-Business applications running on application servers, the application code is composed of several components, and it runs on top of middleware that is itself composed of multiple components. Because of the layering of components in these large applications, call stacks are deep (average stack depth: 27-75 in the applications we studied), the number of method invocations can be in millions (24000-35 million invocations in the applications we studied), and the total size of allocated bytes on the heap in these invocations can be large (89000 bytes-452 Mb in the applications we studied). In understanding and tuning the performance of such large systems, a critical need is tools that can provide a summarization of key performance problems by components of interest to the user.
Current approaches to this problem include summarizing by base costs and cumulative costs for invocations, methods, packages or classes. Base cost reflects the cost of an invocation minus any costs of its callees. Cumulative costs reflect the cost of an invocation and its callees. Summarization by methods, classes or packages is at too coarse a level of granularity because the calling context is lost in these metrics, and calling context is critical for performance analysis. Summarization by invocations provides too much unnecessary data in which the user might not be interested. Examples of common code patterns that contain uninteresting invocations include:
The wrapper pattern: It is common for invocations to wrap or delegate to other functions that perform the actual work. Wrapper invocations are therefore uninteresting from a performance analysis standpoint. The only means to filter these out is to summarize invocations by base costs rather than cumulative costs, since wrapper invocations have low base costs, but high cumulative costs.
The tail-library pattern: It is common for application code to make many calls to library functions or middleware code, at the tail of a call sequence. These are functions that the user has little interest in performance tuning; so they are likely candidates for filtering. Yet, their costs cannot be entirely ignored. As an example, take the case where an application method foo( ) has numerous calls to HashMap.put which are cumulatively expensive. The cost of each HashMap.put call is insignificant in the base cost summary, as is the base cost of foo( ). Yet, from the application developer's perspective, it is often useful to understand that foo( ) has a large cumulative cost, because it often reflects poor application design, or inaccurate use of middleware or library functions. This understanding can be obtained by summaries of cumulative costs of foo( ). Note that here, we need a summary of cumulative costs rather than base costs, whereas we needed a base costs summary to handle the wrapper pattern.
The sandwiching pattern: It is common for applications to call middleware or library code, which then callback the application code within the same call sequence. As an example, foo( ) may call some EJB (ENTERPRISE JAVABEANS™ program) container functions c1( ) and c2( ), which then callback the application function bar( ). Using cumulative costs alone for identifying expensive invocations is inadequate because of double counting (e.g., foo's costs include those of bar in this measure). Using base costs would miss the costs of calls to the middleware functions c1 and c2 for reasons described in the previous paragraph.
Therefore there is a need for a method and tool for summarizing application performance that overcomes the above shortcomings.